package com.mjkj.demo.utils;


import com.mjkj.demo.utils.date.WeekDto;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author XuDoom
 * @date 2023/4/4 10:05
 */
public class SpiltDateUtil {
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");


    public static String dateFormat(String dateStr, String timeStr){
        SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat inputTimeFormat = new SimpleDateFormat("HHmmss");
        SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat outputTimeFormat = new SimpleDateFormat("HH:mm:ss");

        try {
            Date date = inputDateFormat.parse(dateStr);
            Date time = inputTimeFormat.parse(timeStr);
            return outputDateFormat.format(date) + " " + outputTimeFormat.format(time);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static List<WeekDto> getWeek(String start, String end) {
        List<Long> beginDateList = new ArrayList<Long>();
        List<Long> endDateList = new ArrayList<Long>();
        List<WeekDto> weekDtoList = new ArrayList<>();
        Date startDate = null;
        Date endDate = null;
        try {
            startDate = simpleDateFormat.parse(start);
            endDate = simpleDateFormat.parse(end);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        SimpleDateFormat sdw = new SimpleDateFormat("E");
        Calendar calendar = Calendar.getInstance();
        String begin = sdw.format(startDate);
        calendar.setTime(startDate);
        beginDateList.add(calendar.getTimeInMillis());
        if ("星期一".equals(begin)) {
            addTimeStamp(beginDateList, endDateList,weekDtoList, startDate, endDate, sdw, calendar);
        } else {
            if ("星期日".equals(sdw.format(startDate))) {
                Calendar special = Calendar.getInstance();
                special.setTime(startDate);
                special.set(Calendar.HOUR_OF_DAY, 23);
                special.set(Calendar.MINUTE, 59);
                special.set(Calendar.SECOND, 59);
                endDateList.add(special.getTime().getTime());
            }
            addTimeStamp(beginDateList, endDateList, weekDtoList, startDate, endDate, sdw, calendar);
        }
        return weekDtoList;
    }

    private static void addTimeStamp(List<Long> beginDateList, List<Long> endDateList,List<WeekDto> weekDtoList, Date startDate, Date endDate, SimpleDateFormat sdw, Calendar calendar) {
        while (startDate.getTime() < endDate.getTime()) {
            calendar.add(Calendar.DAY_OF_YEAR, 1);
            startDate = calendar.getTime();
            if ("星期一".equals(sdw.format(startDate))) {
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                beginDateList.add(calendar.getTimeInMillis());
            } else if ("星期日".equals(sdw.format(startDate)) || startDate.getTime() >= endDate.getTime()) {
                if (startDate.getTime() <= endDate.getTime()) {
                    calendar.set(Calendar.HOUR_OF_DAY, 23);
                    calendar.set(Calendar.MINUTE, 59);
                    calendar.set(Calendar.SECOND, 59);
                    endDateList.add(calendar.getTimeInMillis());
                } else {
                    endDateList.add(endDate.getTime());
                }
            }
        }
        for (int i = 0; i < beginDateList.size(); i++) {
            WeekDto weekDto = new WeekDto();
            Long beginStr = beginDateList.get(i);
            Long endStr;
            try {
                endStr = endDateList.get(i);
            }catch (Exception n) {
                endStr = System.currentTimeMillis();
            }
            Date bDate = new Date(beginStr);
            Date eDate = new Date(endStr);
            calendar.setFirstDayOfWeek(Calendar.MONDAY);
            // 设置当前日期
            calendar.setTime(bDate);
            String begin1 = simpleDateFormat.format(bDate);
            String end1 = simpleDateFormat.format(eDate);
            weekDto.setWeekBegin(begin1);
            weekDto.setWeekEnd(end1);
            weekDto.setWeekNum(calendar.get(Calendar.WEEK_OF_YEAR)+"");
            weekDto.setKey(calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.WEEK_OF_YEAR)));
            weekDtoList.add(weekDto);
            System.out.println("Key：" + weekDto.getKey() + ",以:" + calendar.getTimeInMillis() + "时间计算，时间段为：" + begin1 + "～" + end1);
        }
    }

    /**
     *  将时间段按星期分割
     */
    public static final List<Range> splitToWeeks(Date start, Date end) {
        List<Range> result = new ArrayList<>();
        result.add(Range.create(start));
        Date from = new Date(start.getTime() + 7L * 24 * 3600 * 1000);
        Date weekEnd = cn.hutool.core.date.DateUtil.endOfWeek(end);
        while (from.compareTo(weekEnd) <= 0) {
            Date dt = cn.hutool.core.date.DateUtil.beginOfWeek(from);

            CollectionUtil.last(result).end(new Date(dt.getTime() - 24L * 3600 * 1000));
            result.add(Range.create(dt));
            from.setTime(from.getTime() + 7L * 24 * 3600 * 1000);
        }
        CollectionUtil.last(result).end(end);
        return result;
    }

    /**
     * 将时间段按照月分割
     * @param start
     * @param end
     * @return
     */
    public static final List<Range> splitToMonths(Date start, Date end) {
        List<Range> result = new ArrayList<>();
        result.add(Range.create(start));
        Calendar cal = Calendar.getInstance();
        cal.setTime(start);
        cal.add(Calendar.MONTH, 1);
        Date monthEnd = cn.hutool.core.date.DateUtil.endOfMonth(end);
        while (cal.getTimeInMillis() <= monthEnd.getTime()) {
            Date dt = cn.hutool.core.date.DateUtil.beginOfMonth(cal.getTime());
            CollectionUtil.last(result).end(new Date(dt.getTime() - 24L * 3600 * 1000));
            result.add(Range.create(dt));
            cal.add(Calendar.MONTH, 1);
        }
        CollectionUtil.last(result).end(end);
        return result;
    }

    /**
     * 将时间段按照季度分割
     * @param start
     * @param end
     * @return
     */
    public static final List<Range> splitToQuarts(Date start, Date end) {
        List<Range> result = new ArrayList<>();
        result.add(Range.create(start));
        Calendar cal = Calendar.getInstance();
        cal.setTime(start);
        cal.add(Calendar.MONTH, 3);
        Date quartEnd = cn.hutool.core.date.DateUtil.endOfQuarter(end);
        while (cal.getTimeInMillis() <= quartEnd.getTime()) {
            Date dt = cn.hutool.core.date.DateUtil.beginOfQuarter(cal.getTime());
            CollectionUtil.last(result).end(new Date(dt.getTime() - 24L * 3600 * 1000));
            result.add(Range.create(dt));
            cal.add(Calendar.MONTH, 3);
        }
        CollectionUtil.last(result).end(end);
        return result;
    }

    /**
     * 将时间段按照半年分割
     * @param start
     * @param end
     * @return
     */
    public static final List<Range> splitToHalfOfYears(Date start, Date end) {
        List<Range> result = new ArrayList<>();
        result.add(Range.create(start));
        Calendar cal = Calendar.getInstance();
        cal.setTime(start);
        cal.add(Calendar.MONTH, 6);
        int mon = cal.get(Calendar.MONTH);
        Calendar tmp = Calendar.getInstance();
        if (mon < 6) {
            tmp.setTimeInMillis(cal.getTimeInMillis());
            tmp.set(Calendar.MONTH, 5);
        } else {
            tmp.setTimeInMillis(cal.getTimeInMillis());
            tmp.set(Calendar.MONTH, 11);
        }
        Calendar halfYearEnd = cn.hutool.core.date.DateUtil.endOfMonth(tmp);
        while (cal.getTimeInMillis() <= halfYearEnd.getTimeInMillis()) {
            mon = cal.get(Calendar.MONTH);
            Calendar cal1 = Calendar.getInstance();
            if (mon < 6) {
                cal1.setTimeInMillis(cal.getTimeInMillis());
                cal1.set(Calendar.MONTH, 0);
            } else {
                cal1.setTimeInMillis(cal.getTimeInMillis());
                cal1.set(Calendar.MONTH, 6);
            }
            Date dt = cn.hutool.core.date.DateUtil.beginOfMonth(cal1.getTime());
            CollectionUtil.last(result).end(new Date(dt.getTime() - 24L * 3600 * 1000));
            result.add(Range.create(dt));
            cal.add(Calendar.MONTH, 6);
        }
        CollectionUtil.last(result).end(end);
        return result;
    }

    /**
     * 将时间段按照年分割
     * @param start
     * @param end
     * @return
     */
    public static final List<Range> splitToYears(Date start, Date end) {
        List<Range> result = new ArrayList<>();
        result.add(Range.create(start));
        Calendar cal = Calendar.getInstance();
        cal.setTime(start);
        cal.add(Calendar.YEAR, 1);
        Date yearEnd = cn.hutool.core.date.DateUtil.endOfYear(end);
        while (cal.getTimeInMillis() <= yearEnd.getTime()) {
            Date dt = cn.hutool.core.date.DateUtil.beginOfYear(cal.getTime());
            CollectionUtil.last(result).end(new Date(dt.getTime() - 24L * 3600 * 1000));
            result.add(Range.create(dt));
            cal.add(Calendar.YEAR, 1);
        }
        CollectionUtil.last(result).end(end);
        return result;
    }

    public static class Range {
        Date start;
        Date end;

        private Range(Date start) {
            this.start = start;
        }

        public static Range create(Date start) {
            return new Range(start);
        }

        public Range end(Date end) {
            this.end = end;
            return this;
        }

        public Date getStart() {
            return start;
        }

        public Date getEnd() {
            return end;
        }

        @Override
        public String toString() {
            return "[" + cn.hutool.core.date.DateUtil.format(start, "yyyy-MM-dd") + "-" + cn.hutool.core.date.DateUtil.format(end, "yyyy-MM-dd")
                    + "]";
        }
    }

}
